#include <SN8P2711B.h>

#define TRUE		1
#define FALSE	0

#define _LIGHT_ON	0
#define _LIGHT_OFF	1

#define _KEY_PRESS_DOWN	1
#define _KEY_PRESS_UP		0
#define _KEY_NULL			0x00
#define _KEY_CLICK			0x01
//#define _KEY_DCLICK			0x02
#define _KEY_LONGPRESSED	0x03

#if 0
#define _LED1			(FP03)	//output
#define _LED2			(FP02)	//output
#define _LED3			(FP53)	//output
#define _LED4			(FP54)	//output
#else
#define _LED1			(FP54)	//output
#define _LED2			(FP53)	//output
#define _LED3			(FP02)	//output
#define _LED4			(FP03)	//output
#endif
#define _LED5			(FP43)	//output
#define _OUT_EN			(FP41)	//output
#define _KEY_DETECT		(FP04)	//input
#define _VIN_DETECT		(FP01)	//input
//#define _LIPOW_DETECT	(FP44)	//input	AIN4

#define _20MSTIMEOUT		10		// 20 ms
#define _100MSTIMEOUT		50		// 100 ms
#define _500MSTIMEOUT		5		// 500 ms = _100MSTIMEOUT x 5
#define _1000MSTIMEOUT		10		// 1 Sec = _100MSTIMEOUT x 10
#define _1MinTIMEOUT		60		// 1 min = _1000MSTIMEOUT x 60
#define _30MinTIMEOUT		30		// 1 min = _1MinTIMEOUT x 30
#define _SLEEPTIMEOUT		25		// 30 Sec = _1000MSTIMEOUT x 25

typedef enum
{
	EN_STATE_IDLE	= 0x00,
	EN_STATE_OUTPUT,
	EN_STATE_CHARGE,
	//EN_STATE_CHARGE_OK,
	EN_STATE_LOWPWOER,
	EN_STATE_SLEEP,
	EN_STATE_TOTAL

} EN_STATE;

EN_STATE enState = EN_STATE_IDLE;	//0:ilde, 1:Li Charge,  2:Output

//bit g2MsTimeoutTick = FALSE;
bit g20MsTimeoutTick = FALSE;
bit g100MsTimeoutTick = FALSE;
//bit g500MsTimeoutTick = FALSE;
bit g1000MsTimeoutTick = FALSE;
bit gsleepTimeoutTick = FALSE;
bit g1MinTimeoutTick = FALSE;
bit g30MinTimeoutTick = FALSE;
bit gbFristPowerOn = TRUE;
bit gbFristPowerOn2 = TRUE;
bit gbProtectionSleep = FALSE;
bit gbChargeOK = FALSE;
bit gbOutputChargeOK = FALSE;
bit gbDeviceInsert = FALSE;
bit gbBootingState = TRUE;
bit gucADCSel = 0;
bit gbSleepState = FALSE;
unsigned char g5MsTimeoutCount = 0;
unsigned char g20MsTimeoutCount = 0;
unsigned char g100MsTimeoutCount = 0;
unsigned char g500MsTimeoutCount = 0;
unsigned char g1000MsTimeoutCount = 0;
unsigned char g1MinTimeoutCount = 0;
unsigned char g30MinTimeoutCount = 0;
unsigned char gsleepTimeoutCount = 0;
unsigned char glowPowerTimeoutCount = 0;
unsigned char ucPowerPercent = 0xFF;
unsigned char gsleepTimeoutTotal = _SLEEPTIMEOUT;

unsigned char ucADCValBuf[6];	
unsigned char ucADCCount = 0;

//void DELAY(unsigned int i);
//void IO_Setting(void);
//void Timer_Setting(void);
//void ADC_Setting(void);

unsigned char Key_Scan(void);
void systemChangeState(EN_STATE enStateVal);
void showInfoLEDsByLIPower(unsigned char ucPercent);
//void AIN4ADCHandel(unsigned char ulDataH, unsigned char ulDataL);
void AIN2ADCHandel(void);
void ADC_Process(void);

void main(void)
{
	unsigned char keyPressed = _KEY_NULL;

	//WDTR = 0x5A;
	//IO_Setting();
	//Timer_Setting();
	//ADC_Setting();

	P0M = 0x0D;	//P0 Input-Output value
	P0UR = 0x00;	//P0 pull up value
	P0 = 0X01;	//P0 register value
	P4M = 0x0A;	//P4 Input-Output value	0x0E
	P4UR = 0x00;     //P4 pull up value
	P4CON = 0x15;	//P4 Analog-Digital value	0x11
	P4 = 0X00;	//P4 register value
	P5M = 0x18;	//P5 Input-Output value
	P5UR = 0x00;	//P5 pull up value
	P5 = 0X00;	//P5 register value	

	TC0M = 0x24;	//TC0M register value, Fcpu: 1.000000MHZ
	FTC0X8 = 0;	//CLK source: Fcpu
	TC0C = 0x64;	//TC0C register value, time: 10.000000ms(100.000000HZ)
	TC0R = 0x64;	//TC0R register value
	FTC0IRQ = 0;
	FTC0IEN = 1;	//TC0 Interrupt enable
	FTC0CKS = 0;
	FTC0ENB = 1;	//TC0 enable

	ADM = 0x02;	//ADC input channel mode: AIN4
	FGCHS = 1;	//AIN channel enable
	//_DELAY(100); //User support DELAY function
	ADR = 0x00;	//ADC clock: 1.000000MHZ,ADC resolution: -1
	VREFH = 0x00;	//Internal VREFH: NULL
	FEVHENB = 1;	//Internal VREFH disable
	FADENB = 1;
	FADCIRQ = 0;
	FADCIEN = 1;	//Interrupt enable
	FEOC = 0;
	//FADS = 1;

#if 0
	_LED1 = _LIGHT_OFF;
	_LED2 = _LIGHT_OFF;
	_LED3 = _LIGHT_OFF;
	_LED4 = _LIGHT_OFF;
	_LED5 = FALSE;
#else
	//_LED1 = _LIGHT_ON;
	//_LED2 = _LIGHT_ON;
	//_LED3 = _LIGHT_ON;
	//_LED4 = _LIGHT_ON;
	//_LED5 = FALSE;
#endif
	//_CHARGE_ON_OFF = FALSE;
	//_OUT_EN = TRUE;

	FGIE = 1;

	while(1)
	{
		//WDTR = 0x5A;

		if(gbFristPowerOn)
		{
			if (gbFristPowerOn2)
			{
				continue;
			}
			
			systemChangeState(EN_STATE_SLEEP);
			gbFristPowerOn = FALSE;			
		}
		
		if(g20MsTimeoutTick)
		{
			g20MsTimeoutTick = FALSE;

			keyPressed = Key_Scan();
			if (keyPressed == _KEY_LONGPRESSED)
			{
				if ((enState == EN_STATE_OUTPUT)||(enState == EN_STATE_IDLE))
					_LED5 = !_LED5;
			}

			
		}

/*
		if(g100MsTimeoutTick)
		{
			g100MsTimeoutTick = FALSE;
			if (glowPowerTimeoutCount > 0)
				glowPowerTimeoutCount--;			

		}
*/
#if 0
		if(g500MsTimeoutTick)
		{
			g500MsTimeoutTick = FALSE;
			//_LED3 = !_LED3;
			/*
			if(enState == EN_STATE_CHARGE)
			{
				showInfoLEDsByLIPower(ucPowerPercent, TRUE);
			}
			else if((enState == EN_STATE_OUTPUT)||(enState == EN_STATE_IDLE))
			{
				if(ucPowerPercent<25) 
					showInfoLEDsByLIPower(ucPowerPercent, TRUE);
				else
					showInfoLEDsByLIPower(ucPowerPercent, FALSE);
			}
			*/
			if(enState != EN_STATE_LOWPWOER)
			{
				showInfoLEDsByLIPower(ucPowerPercent);
			}
			
		}
#endif
		/*
		if(g1000MsTimeoutTick)
		{
			g1000MsTimeoutTick = FALSE;
			//_LED4 = !_LED4;			
		}
		*/
		if (gbBootingState)
		{
			_OUT_EN = TRUE;
			continue;
		}

		if (_VIN_DETECT)
		{
			if (enState!=EN_STATE_CHARGE)
				systemChangeState(EN_STATE_CHARGE);
		}
		
		switch(enState)
		{
			case EN_STATE_IDLE:		//ilde
				_OUT_EN = TRUE;
				if (ucPowerPercent != 0)
				{
					if(gsleepTimeoutTick)
					{
						gsleepTimeoutTick = FALSE;
						
						if (_LED5 == FALSE)
						{
							systemChangeState(EN_STATE_SLEEP);
							continue;					
						}
						else
						{
							gbSleepState = TRUE;
							_LED1 = _LIGHT_OFF;
							_LED2 = _LIGHT_OFF;
							_LED3 = _LIGHT_OFF;
							_LED4 = _LIGHT_OFF;	
							//_OUT_EN = FALSE;
						}
					}

					if (keyPressed != _KEY_NULL)
					{
						gsleepTimeoutCount = 0;
						gbSleepState = FALSE;
					}

					if (gbDeviceInsert == 1)	//device insert
					{
						systemChangeState(EN_STATE_OUTPUT);						
					}						
				}
				else
				{
					systemChangeState(EN_STATE_LOWPWOER);
				}
				break;
			case EN_STATE_LOWPWOER:
				//LED1 flash 3 times then change to IDLE
				if (glowPowerTimeoutCount)
				{					
					_LED1 = glowPowerTimeoutCount&0x01;				
				}
				else
				{
					systemChangeState(EN_STATE_SLEEP);
				}				
				break;
			case EN_STATE_CHARGE:		//Charge
				//if((ucPowerPercent == 100) || ((ucPowerPercent == 99)&&(gbChargeOK)))
				/*
				if(gbChargeOK)
				{
					systemChangeState(EN_STATE_CHARGE_OK);
				}*/				

				if (!_VIN_DETECT)
				{
					systemChangeState(EN_STATE_SLEEP);
				}

				/*
				if (gbChargeOK)
				{
					systemChangeState(EN_STATE_SLEEP);
				}
				*/
				break;
				/*
			case EN_STATE_CHARGE_OK:
				if (!_VIN_DETECT)
				{
					systemChangeState(EN_STATE_SLEEP);
				}
				break;
				*/
			case EN_STATE_OUTPUT:		//Output
				if((gbProtectionSleep)||(gbOutputChargeOK))
				{						
					systemChangeState(EN_STATE_SLEEP);
					continue;
				}
				
				if(ucPowerPercent == 0)
				{
					systemChangeState(EN_STATE_LOWPWOER);
				}
				else
				{
					//if ((gbLoadStateChange==1) && (gbLoadState == 0))	//no device insert
					if (gbDeviceInsert == 0)	//no device insert
					{
						//_LED5=1;
						//gbLoadState = 0;
						//showInfoLEDsByLIPower(ucPowerPercent, FALSE);
						systemChangeState(EN_STATE_IDLE);
						gsleepTimeoutTotal = 4;	//5Sec
					}
				}
				break;
		}
		
	}

}

/*
void IO_Setting(void)
{
  P0M = 0x0D;	//P0 Input-Output value
  P0UR = 0x02;	//P0 pull up value
  P0 = 0X01;	//P0 register value
  P4M = 0x0A;	//P4 Input-Output value	0x0E
  P4UR = 0x00;     //P4 pull up value
  P4CON = 0x15;	//P4 Analog-Digital value	0x11
  P4 = 0X00;	//P4 register value
  P5M = 0x18;	//P5 Input-Output value
  P5UR = 0x00;	//P5 pull up value
  P5 = 0X00;	//P5 register value
}

void Timer_Setting(void)
{
  TC0M = 0x24;	//TC0M register value, Fcpu: 1.000000MHZ
  FTC0X8 = 0;	//CLK source: Fcpu
  TC0C = 0x64;	//TC0C register value, time: 10.000000ms(100.000000HZ)
  TC0R = 0x64;	//TC0R register value
  FTC0IRQ = 0;
  FTC0IEN = 1;	//TC0 Interrupt enable
  FTC0CKS = 0;
  FTC0ENB = 1;	//TC0 enable
}

void ADC_Setting(void)
{
	ADM = 0x04;	//ADC input channel mode: AIN4
	FGCHS = 1;	//AIN channel enable
	FADENB = 1;
	//_DELAY(100); //User support DELAY function
	FADCIRQ = 0;
	FADCIEN = 1;	//Interrupt enable
	ADR = 0x60;	//ADC clock: 1.000000MHZ,ADC resolution: -1
	VREFH = 0x00;	//Internal VREFH: NULL
	FEVHENB = 1;	//Internal VREFH disable

	FADS = 1;
}
*/

__interrupt ISR(void)
{
	//unsigned long lldata = 0;

	if(FTC0IRQ)
	{
		FTC0IRQ=0;

		//if (g5MsTimeoutCount < 2)
		g5MsTimeoutCount++;

		if (g5MsTimeoutCount == 2)
		{
			FADS = 1;
			//g5MsTimeoutCount = 0xff;
		}			
		
		g20MsTimeoutCount++;
		if (g20MsTimeoutCount >= _20MSTIMEOUT)		//20ms
		{
			g20MsTimeoutCount = 0;
			g20MsTimeoutTick = TRUE;
		}

		g100MsTimeoutCount++;
		if (g100MsTimeoutCount >= _100MSTIMEOUT)		//100ms
		{
			g100MsTimeoutCount = 0;
			g100MsTimeoutTick = TRUE;

			if (glowPowerTimeoutCount > 0)
				glowPowerTimeoutCount--;			

			g500MsTimeoutCount++;
			if (g500MsTimeoutCount >= _500MSTIMEOUT)		//500ms
			{
				g500MsTimeoutCount = 0;
				//g500MsTimeoutTick = TRUE;

				//if(gbBootingState)
				gbBootingState = FALSE;					

				if(enState != EN_STATE_LOWPWOER)
				{
					showInfoLEDsByLIPower(ucPowerPercent);
				}
			}

			g1000MsTimeoutCount++;
			if (g1000MsTimeoutCount >= _1000MSTIMEOUT)		//1Sec
			{
				g1000MsTimeoutCount = 0;
				g1000MsTimeoutTick = TRUE;			

				gbFristPowerOn2 = FALSE;
									
				g1MinTimeoutCount++;
				if (g1MinTimeoutCount >= _1MinTIMEOUT)		// 1Min
				{
					g1MinTimeoutCount = 0;
					g1MinTimeoutTick = TRUE;

					//if (ucPowerPercent == 99)
					if (ucPowerPercent == 9)
					{
						g30MinTimeoutCount++;
						if (g30MinTimeoutCount >= _30MinTIMEOUT)		// 30Min
						{
							g30MinTimeoutCount = 0;
							g30MinTimeoutTick = TRUE;
							gbChargeOK = TRUE;
						}
					}
					else
					{
						g30MinTimeoutCount = 0;
						g30MinTimeoutTick = FALSE;
					}
				}
				
				//if (gbFristPowerOn == TRUE)
				//	gbFristPowerOn = FALSE;
				
				if (enState == EN_STATE_IDLE)
				{
					gsleepTimeoutCount++;
					//if (++gsleepTimeoutCount >= _SLEEPTIMEOUT)		//sleeptimeout
					if (gsleepTimeoutCount >= gsleepTimeoutTotal)		//sleeptimeout
					{
						gsleepTimeoutCount = 0;
						gsleepTimeoutTick = TRUE;				
					}
				}
				else
				{
					gsleepTimeoutCount = 0;
					gsleepTimeoutTick = FALSE;				
				}
			}		
		}
	}


	if((FADCIEN==1)&&(FADCIRQ==1))
	{
		if (FEOC)
		{	
			//lldata = ADB;
			//lldata = (lldata<<4) |(ADR&0x0F);
			//getADCHandel(lldata);
				
			if(gucADCSel == 0)
			{
				ADC_Process();
			}
			else
			{
				AIN2ADCHandel();
			}
		}
	}
	
#if 0
	if((FADCIEN==1)&&(FADCIRQ==1))
	{
		if (FEOC)
		{	
			lldata = ADB;
			lldata = (lldata<<4) |(ADR&0x0F);
			getPowerPercent(lldata);

			FADCIRQ=0;
	  		FADS = 1;	
		}
	}
#endif	
}
/*
void DELAY(unsigned int i)
{
	unsigned int  j;
	for (j=i;j>0;j--)
	NOP(1);
}
*/

void showInfoLEDsByLIPower(unsigned char ucPercent)
{
	if (gbBootingState)
		return;

	if (gbSleepState)
		return;
/*		
	if (gbChargeOK)
	{
		ucPercent = 5;
	}
*/	
	//switch(ucPercent)
	{
		if(ucPercent == 1)
		{
			_LED1 = !_LED1;
			_LED2 = _LIGHT_OFF;
			_LED3 = _LIGHT_OFF;
			_LED4 = _LIGHT_OFF;
		}
		if(ucPercent == 2)
		{
			_LED1 = _LIGHT_ON;
			_LED2 = _LIGHT_OFF;
			_LED3 = _LIGHT_OFF;
			_LED4 = _LIGHT_OFF;
		}
		if(ucPercent == 3)
		{
			_LED1 = _LIGHT_ON;
			_LED2 = _LIGHT_ON;
			_LED3 = _LIGHT_OFF;
			_LED4 = _LIGHT_OFF;
		}
		if(ucPercent == 4)
		{
			_LED1 = _LIGHT_ON;
			_LED2 = _LIGHT_ON;
			_LED3 = _LIGHT_ON;
			_LED4 = _LIGHT_OFF;
		}
		if((ucPercent == 5) ||(ucPercent == 9))
		{
			_LED1 = _LIGHT_ON;
			_LED2 = _LIGHT_ON;
			_LED3 = _LIGHT_ON;
			_LED4 = _LIGHT_ON;
		}
		if(ucPercent == 6)
		{
			_LED1 = _LIGHT_ON;
			_LED2 = !_LED2;
			_LED3 = _LIGHT_OFF;
			_LED4 = _LIGHT_OFF;
		}
		if(ucPercent == 7)
		{
			_LED1 = _LIGHT_ON;
			_LED2 = _LIGHT_ON;
			_LED3 = !_LED3;
			_LED4 = _LIGHT_OFF;
		}
		if(ucPercent == 8)
		{
			_LED1 = _LIGHT_ON;
			_LED2 = _LIGHT_ON;
			_LED3 = _LIGHT_ON;
			_LED4 = !_LED4;
		}
	}
}

#if 0
unsigned char Key_Scan(void)
{
	static unsigned char Key_State   = 0;        //
	static unsigned char Key_Delay   = 0;        //

	unsigned char Key_Press  = _KEY_PRESS_DOWN;           //
	unsigned char Key_Return = _KEY_NULL;           //

	Key_Delay++;

	//set key detect IO to input
	Key_Press = _KEY_DETECT;//Get_Key();

	switch (Key_State)
	{
		case 0://key init
			Key_Delay = 0;
			if (Key_Press == _KEY_PRESS_DOWN)//
			{
				Key_State = 1;//turn to key conform state				
			}
			break;

		case 1://key conform state
			if (Key_Press == _KEY_PRESS_DOWN)//conform the last key press
			{
				Key_State = 2;//turn to key long time press
				Key_Return = _KEY_CLICK;
			}
			else//
			{
				Key_State = 0;
			}
			break;

		case 2://
			if (Key_Press == _KEY_PRESS_DOWN)//
			{
				if (Key_Delay>80u)	// 3Sec
				{
					Key_State = 5;
					Key_Return  = _KEY_LONGPRESSED;
				}			
			}
			else
			{
				Key_State = 0;
				/*
				if (Key_Delay<20)	// 200ms
				{
					Key_State = 3;
				}
				else
				{
					Key_State = 0;
				}
				*/
			}			
			break;
/*
		case 3:
			if (Key_Delay<20)	// 200ms
			{
				Key_State = 0;
				Key_Return  = _KEY_CLICK;
				break;
			}

			if (Key_Press != _KEY_NULL )
			{
				Key_State = 4;
			}
			break;

		case 4:
			if (Key_Press != _KEY_NULL )
			{
				Key_State = 0;
				Key_Return  = _KEY_DCLICK;
			}
			else
			{
				Key_State = 0;
				Key_Return  = _KEY_NULL;
			}
			break;
*/
		case 5:
			if (Key_Press == _KEY_PRESS_UP)
			{
				Key_State = 0;
			}
			break;
		default :
			break;
	}

	return Key_Return;
}
#else
unsigned char Key_Scan(void)
{
	static unsigned char Key_State   = 0;        //
	static unsigned char Key_Delay   = 0;        //

	bit Key_Press  = _KEY_PRESS_DOWN;           //
	unsigned char Key_Return = _KEY_NULL;           //

	Key_Delay++;

	//set key detect IO to input
	Key_Press = _KEY_DETECT;//Get_Key();

	if(Key_State == 0)//key init
	{
		Key_Delay = 0;
		if (Key_Press == _KEY_PRESS_DOWN)//
		{
			Key_State = 1;//turn to key conform state				
		}
	}

	if(Key_State == 1)//key conform state
	{
			if (Key_Press == _KEY_PRESS_DOWN)//conform the last key press
			{
				Key_State = 2;//turn to key long time press
				Key_Return = _KEY_CLICK;
			}
			else//
			{
				Key_State = 0;
			}
	}
	
	if(Key_State == 2)//
	{
		if (Key_Press == _KEY_PRESS_DOWN)//
		{
			if (Key_Delay>80u)	// 3Sec
			{
				Key_State = 3;
				Key_Return  = _KEY_LONGPRESSED;
			}			
		}
		else
		{
			Key_State = 0;
		}			
	}

	if(Key_State == 3)
	{
		if (Key_Press == _KEY_PRESS_UP)
		{
			Key_State = 0;
		}
	}

	return Key_Return;
}
#endif
void systemChangeState(EN_STATE enStateVal)
{
	//if(enStateVal >= EN_STATE_TOTAL)
		//return;

	enState = enStateVal;
	gbSleepState = FALSE; 
	gsleepTimeoutTotal = _SLEEPTIMEOUT;
	
	if (enStateVal == EN_STATE_IDLE)
	{
		//_LED1 = _LIGHT_OFF;
		//_LED2 = _LIGHT_OFF;
		//_LED3 = _LIGHT_OFF;
		//_LED4 = _LIGHT_OFF;
		//_LED5 = FALSE;
		_OUT_EN = TRUE;
		//_CHARGE_ON_OFF = FALSE;
		//ucPowerPercent = 5;
	}

	if (enStateVal == EN_STATE_LOWPWOER)
	{
		_LED1 = _LIGHT_ON;
		_LED2 = _LIGHT_OFF;
		_LED3 = _LIGHT_OFF;
		_LED4 = _LIGHT_OFF;
		_LED5 = FALSE;
		_OUT_EN = FALSE;
		glowPowerTimeoutCount = 4;
		//ucPowerPercent = 0;
		//NOP(1);
	}	

	if (enStateVal == EN_STATE_CHARGE)
	{
		_LED5 = FALSE;
		_OUT_EN = FALSE;
		//_CHARGE_ON_OFF = TRUE;
		ucPowerPercent = 1;
	}

	if (enStateVal == EN_STATE_OUTPUT)
	{
		//_CHARGE_ON_OFF = FALSE;
		_OUT_EN = TRUE;			
		//DELAY(100);
		ucPowerPercent = 5;
	}
	/*
	else if (enStateVal == EN_STATE_CHARGE_OK)
	{
		_LED1 = _LIGHT_ON;
		_LED2 = _LIGHT_ON;
		_LED3 = _LIGHT_ON;
		_LED4 = _LIGHT_ON;
		_LED5 = FALSE;

		//_CHARGE_ON_OFF = FALSE;
		_OUT_EN = FALSE;		
		ucPowerPercent = 5;
	}
	*/
	if (enStateVal == EN_STATE_SLEEP)
	{
		_LED1 = _LIGHT_OFF;
		_LED2 = _LIGHT_OFF;
		_LED3 = _LIGHT_OFF;
		_LED4 = _LIGHT_OFF;
		_LED5 = FALSE;
		_OUT_EN = FALSE;	
		//_LED4 = 0;	//for test
		FGIE = 0;
		ADM = 0x00;
		FP00 = 0;
		NOP(3);
		SLEEPMODE;
		NOP(3);
		
		//_LED5 = 1;	//for test
		
		//init all data
		g20MsTimeoutTick = FALSE;
		g100MsTimeoutTick = FALSE;
		//g500MsTimeoutTick = FALSE;
		g1000MsTimeoutTick = FALSE;
		gsleepTimeoutTick = FALSE;
		g20MsTimeoutCount = 0;
		g100MsTimeoutCount = 0;
		g500MsTimeoutCount = 0;
		g1000MsTimeoutCount = 0;
		gsleepTimeoutCount = 0;
		glowPowerTimeoutCount = 0;
		//if (ucPowerPercent==0)
		//ucPowerPercent = 0xFF;
		gbDeviceInsert = FALSE;
		gbBootingState = TRUE;
		//gbNewLoadState = 0;
		//gbLoadStateChange = 0;
		//gADCCount = 0;
		gbProtectionSleep = FALSE;
		g30MinTimeoutTick = FALSE;
		gbChargeOK = FALSE;
		ucADCCount = 0;
		gucADCSel = 0;
		g5MsTimeoutCount = 0;
		
		if (ucPowerPercent>=6)
			ucPowerPercent -= 4;
		
		FP00 = 1;
		ADM = 0x04;	//ADC input channel mode: AIN2
		FGCHS = 1;	//AIN channel enable
		//FADENB = 1;
		ADR = 0x00;	//ADC clock: 1.000000MHZ,ADC resolution: -1
		VREFH = 0x00;	//Internal VREFH: NULL
		FEVHENB = 1;	//Internal VREFH disable		
		FADENB = 1;		
		FADCIRQ = 0;
		FADCIEN = 1;	//Interrupt enable
		FEOC = 0;
		FGIE = 1;
		enState = EN_STATE_IDLE;				
	}

	gbOutputChargeOK = FALSE;
	return;
}

//                     0.5    1     2     3      4
//idle:		3.0	3.3	3.6	3.8	3.95	4.10

//                     0.5   1.5   2.5  3.5    4
//charge:	3.0	3.65	3.85	4.00	4.15

//                     0.5    1     2     3      4
//output:		3.0	3.2	3.5	3.65	3.8	3.95
#if 0
									// 3            3.3          3.6         3.8         3.95           4.1
__ROM unsigned char ADCTable[36] = {0x9Au, 0xf, 0xA9u, 0, 0xB8u, 1, 0xC3u, 2, 0xCAu,  3, 0xD2u, 4,
									// 3         3.65          3.85       4.00        4.15		4.2
									0x9Au, 0, 0xBBu, 0, 0xC5u, 5, 0xCDu,6, 0xD5u,  7,  0xD7, 4,
									// 3             3.2          3.5          3.65        3.8          3.95
									0x9Au, 0xf, 0xA4u, 0, 0xB3u, 1, 0xBBu, 2, 0xC3u,  3, 0xCAu, 4};
								//   4.1        3.95  		3.8		 3.6		3.3             3
__ROM unsigned char ADCTable[36] = {0xD2u, 5, 0xCAu,  4, 0xC3u, 3, 0xB8u, 2, 0xA9u, 1, 0x9Au, 1,  
								//     4.2        4.15         4.00         3.85        3.65         3
									0xD7, 5, 0xD5u,  8, 0xCDu, 7, 0xC5u, 6,  0xBBu, 1, 0x9Au, 1,     
								//     3.95          3.8          3.65          3.5          3.2           3
									0xCAu, 5,  0xC3u,  4, 0xBBu, 3, 0xB3u, 2,  0xA4u, 1, 0x9Au, 1};

__ROM unsigned long ADCTable[36] = {0xD3u, 5, 0xCBu,  4, 0xC3u, 3, 0xB8u, 2, 0xA9u, 1, 0x9Au, 1,  
								//     4.2        4.15         4.00         3.85        3.65         3			2.506
									0xD7, 5, 0xD4u,  8, 0xCCu, 7, 0xC4u, 6,  0xBAu, 1, 0x99u, 1,     
								//     3.95          3.8          3.65          3.5          3.2           3		2.46
									0xCDu, 5,  0xC6u,  4, 0xBEu, 3, 0xB6u, 2,  0xA7u, 1, 0x9Cu, 1};

								//   4.1        3.95  		3.8		 3.6		3.3             3			2.492
__ROM unsigned long ADCTable[18] = {0xD3u, 0xCBu, 0xC3u, 0xB8u, 0xA9u, 0x9Au,   
								//     4.2        4.15         4.00         3.85        3.65         3			2.506
									0xD7, 0xD4u,  0xCCu, 0xC4u, 0xBAu, 0x99u,     
								//     3.95          3.8          3.65          3.5          3.2           3		2.46
									0xCDu, 0xC6u, 0xBEu, 0xB6u, 0xA7u, 0x9Cu};								
								//   4.1        3.95  		3.8		 3.6		3.3             3			2.492
__ROM unsigned long ADCTable[18] = {0xD2Au, 0xCAEu, 0xC33u, 0xB8Fu, 0xA98u, 0x9A2u,   
								//     4.2        4.15         4.00         3.85        3.65         3			2.506
									0xD68, 0xD40u,  0xCC5u, 0xC4Au, 0xBA7u, 0x994u,     
								//     3.95          3.8          3.65          3.5          3.2           3		2.46
									0xCD8u, 0xC5Cu, 0xBDFu, 0xB62u, 0xA68u, 0x9C2u};
								//   4.1        3.95  		3.8		 3.6		3.3             3			2.5
								//   4.1        3.95  	   3.8	  3.6		3.3          3			2.495
__ROM unsigned long ADCTable[18] = {0xD78u, 0xCAAu, 0xC2Fu, 0xB8Bu, 0xA95u, 0x99Eu,   
								//     4.2        4.15        4.00      3.85      3.65         3			2.495
									0xD78u, 0xD4Eu,  0xCD3u, 0xC58u, 0xBB4u, 0x99Eu,     
								//     3.95        3.8      3.65        3.5       3.2           3		2.495
									0xCAAu, 0xC2Fu, 0xBB4u, 0xB38u, 0xA43u, 0x99Eu};

__ROM unsigned char ADCTable[18] = {0xD8u, 0xCBu, 0xC3u, 0xB9u, 0xA9u, 0x9Au, 				//idle
								//     4.2        4.15        4.00      3.85      3.65         3			2.495
									0xD8u, 0xD5u, 0xCDu, 0xC6u, 0xBBu,  0x9Au, 			//charge
								//     3.95        3.8      3.65        3.5       3.2           3		2.495
									0xCBu, 0xC3u, 0xBBu, 0xB4u,  0xA4u, 0x9Au};			//output

__ROM unsigned char ADCTable2[18] = {5, 5, 4, 3, 2, 1,
								     10, 9, 8, 7, 6, 1,
								     5, 5 ,4, 3, 2, 1};
								//   4.2      4.0  	3.8	  3.6		3.3        3			2.495
__ROM unsigned char ADCTable[18] = {0xD8u, 0xCDu, 0xC3u, 0xB9u, 0xA9u, 0x9Au, 			//idle
								//     4.2      4.15     3.95    3.75    3.52      3		2.495
									0xD8u, 0xD5u, 0xCBu, 0xC0u,  0xB5u, 0x9Au,		//charge
								//     4.2       3.82     3.62    3.41      3.1         3			2.495
									0xD8u, 0xC4u, 0xBAu, 0xAFu, 0x9Fu,  0x9Au};		//output

__ROM unsigned char ADCTable2[18] = {5, 5, 4, 3, 2, 1,
								     10, 9, 8, 7, 6, 1,
								     5, 5 ,4, 3, 2, 1};

#else
								//  4.0  	  3.8	      3.6	   3.3        3			2.495
__ROM unsigned char ADCTable[15] = {0xCDu, 0xC3u, 0xB9u, 0xA9u, 0x9Au, 			//idle
								//     4.15    3.95    3.75      3.52      3		2.495
									0xD5u, 0xCBu, 0xC0u,  0xB5u, 0x9Au,		//charge
								//     3.80    3.60    3.39      3.1        3			2.495
									0xC3u, 0xB9u, 0xAEu, 0x9Fu,  0x9Au};		//output

__ROM unsigned char ADCTable2[15] = {5, 4, 3, 2, 1,
								     9, 8, 7, 6, 1,
								     5 ,4, 3, 2, 1};


#endif

#if 0
void getADCHandel(unsigned char ulDataH, unsigned char ulDataL)
{	
	unsigned char ucPercent = 0;
	unsigned char ucADCCount;
	unsigned char ucADCCount2;
	//unsigned char *ucADCCount3;
	
	static unsigned char ucPrevDataH, ucPrevDataL;
	static unsigned char ucPrevDataH2, ucPrevDataL2;

	static unsigned char ucpowerpercentCount = 0;  // confirm powerpercent is ok 
	static unsigned char ucpowerpercentCount2 = 0;  // confirm powerpercent is ok

	//if (ulDataH>0x0D)		//0x0D80	>2.1
		//return;
	
	if(gucADCSel == 0)
	{
		if (ulDataH<=0xD8)		//0x0D80	>2.1
		{
			if((ucPrevDataH==ulDataH)&(ucPrevDataL==ulDataL))
			{
				ucpowerpercentCount++;
				if(ucpowerpercentCount == 5)
				{
					ucpowerpercentCount = 0;

					if (enState == EN_STATE_IDLE)
					{
						ucADCCount2 = 0;
					}
					else	 if (enState == EN_STATE_OUTPUT)
					{
						ucADCCount2 = 24;
					}
					else
					{
						ucADCCount2 = 12;
					}

					for(ucADCCount=0; ucADCCount<6; ucADCCount++)
					{
						if (ulDataH>=ADCTable[ucADCCount2+ucADCCount*2])
						{
							break;
						}
					}

					if (ucADCCount<6)
					{
						ucPercent = ADCTable[ucADCCount2+ucADCCount*2+1];
					}
					else
					{
						ucPercent = 0;
					}

					if(gbLoadState)
					{
						if ((enState == EN_STATE_CHARGE) ||(enState == EN_STATE_CHARGE_OK))
						{
							if (gbChargeOK)
							{
								ucPowerPercent = 4;
							}
							else
							{
								if (ucPercent == 0)
								{
									ucPowerPercent = 1;
								}
								else
								{
									if(ucPercent>=ucPowerPercent)
										ucPowerPercent = ucPercent;								
								}
							}
						}					
						else
						{
							if(ucPercent<=ucPowerPercent)
								ucPowerPercent = ucPercent;
						}
					}
					else
					{
						ucPowerPercent = ucPercent;
					}
						
				}
			}
			else
			{
				ucPrevDataH = ulDataH;
				ucPrevDataL	= ulDataL;
				ucpowerpercentCount = 0;
			}
		}
		
		ADM = 0x02;	//ADC input channel mode: AIN4
		FGCHS = 1;	//AIN channel enable
		FADENB = 1;
		//_DELAY(100); //User support DELAY function
		FADCIRQ = 0;
		//FADCIEN = 1;	//Interrupt enable
		ADR = 0x60;	//ADC clock: 1.000000MHZ,ADC resolution: -1
		//VREFH = 0x00;	//Internal VREFH: NULL
		FEVHENB = 1;	//Internal VREFH disable
		FADS = 1;

		gucADCSel = 1;
	}
	else
	{
		if (ulDataH<=0xD8)		//0x0D80	>2.1
		{
			if((gbLoadState) & (ucPrevDataH2==ulDataH)&(ucPrevDataL2==ulDataL))
			{
				ucpowerpercentCount2++;
				if(ucpowerpercentCount2 == 5)
				{
					ucpowerpercentCount2 = 0;
					//ulData = ulDataH;
					//ulData = ulData<<4 | ulDataL;

					//ulDataH = ulData>>8;
					//ulDataH = ulData&0xFF;
					
					//if (ulData<=0x0004)	//0x50	2.5mv
					if((ulDataH==0)&(ulDataL<=0x04))
					{
						gbDeviceInsert = 0;
					}
					else
					{
						gbDeviceInsert = 1;
					}

					//0.190V=311=0x137	0.180V=295=0x127		0.184V
					//if ((ulData>0x0127)&&(ulData<0x0137))
					if (ulDataH==0x12)
					{
						if((ulDataL>0x0)&&(ulDataL<0xF))
							gbProtectionSleep = TRUE;//go sleep
					}
					if (ulDataH==0x13)
					{
						if((ulDataL>0x0)&&(ulDataL<0xF))
							gbProtectionSleep = TRUE;//go sleep
					}
				}
			}
			else
			{
				ucPrevDataH2 = ulDataH;
				ucPrevDataL2	= ulDataL;
				ucpowerpercentCount2 = 0;
				
			}
		}


		ADM = 0x04;	//ADC input channel mode: AIN4
		FGCHS = 1;	//AIN channel enable
		FADENB = 1;
		//_DELAY(100); //User support DELAY function
		FADCIRQ = 0;
		//FADCIEN = 1;	//Interrupt enable
		ADR = 0x60;	//ADC clock: 1.000000MHZ,ADC resolution: -1
		//VREFH = 0x00;	//Internal VREFH: NULL
		FEVHENB = 1;	//Internal VREFH disable
		FADS = 1;					
		
		gucADCSel = 0;
	}

	return;
}
#else
#if 0
void AIN4ADCHandel(unsigned char ulDataH, unsigned char ulDataL)
{
	unsigned char ucCount, ucCount2;
	static unsigned char ucCountAIN4;
	static unsigned long dataAIN4;
	unsigned long 	dataTemp;

	//if (ulDataH>=0xDA)		//0x0D80	>2.1
		//return;

	if (ucCountAIN4==0)
	{
		dataAIN4 = ulDataH;
		dataAIN4 = dataAIN4<<4;
		dataAIN4 += ulDataL;
		ucCountAIN4++;
	}
	else
	{
		dataTemp =ulDataH;
		dataTemp = dataTemp<<4;
		dataTemp += ulDataL;

		dataAIN4 +=  dataTemp;
		dataAIN4 = dataAIN4>>1;

		if (ucCountAIN4<=6)
		{
			ucCountAIN4++;
		}
		else
		{
			if (enState == EN_STATE_IDLE)
			{
				ucCount2 = 0;
			}
			else	 if (enState == EN_STATE_OUTPUT)
			{
				ucCount2 = 12;
			}
			else
			{
				ucCount2 = 6;
			}

			for(ucCount=0; ucCount<6; ucCount++)
			{
				if (dataAIN4>=ADCTable[(ucCount2+(ucCount<<1))])
				{
					break;
				}
			}

			if (ucCount<6)
			{
				ucPowerPercent = ADCTable2[(ucCount2+(ucCount<<1))];
			}
			else
			{
				ucPowerPercent = 0;
			}
			
		}
	}

	
	ADM = 0x02;	//ADC input channel mode: AIN4
	FGCHS = 1;	//AIN channel enable
	FADENB = 1;
	//_DELAY(100); //User support DELAY function
	FADCIRQ = 0;
	//FADCIEN = 1;	//Interrupt enable
	ADR = 0x60;	//ADC clock: 1.000000MHZ,ADC resolution: -1
	//VREFH = 0x00;	//Internal VREFH: NULL
	FEVHENB = 1;	//Internal VREFH disable
	FADS = 1;

	gucADCSel = 1;
	
	return;


}
#else
#if 0
void AIN4ADCHandel(unsigned char ulDataH, unsigned char ulDataL)
{	
	unsigned char ucPercent = 0;
	unsigned char ucADCCount;
	unsigned char ucADCCount2 =6;
	
	static unsigned char ucPrevDataH, ucPrevDataL;
	static unsigned char ucpowerpercentCount = 0;  // confirm powerpercent is ok 
	
	if (ulDataH<=0xDA)		//0x0D80	>2.1
	{
		if((ucPrevDataH==ulDataH)&(ucPrevDataL==ulDataL))
		{
			ucpowerpercentCount++;
			if(ucpowerpercentCount == 5)
			{
				ucpowerpercentCount = 0;

				if (enState == EN_STATE_IDLE)
				{
					ucADCCount2 = 0;
				}
				else	 if (enState == EN_STATE_OUTPUT)
				{
					ucADCCount2 = 12;
				}
				/*
				else
				{
					ucADCCount2 = 6;
				}*/

				for(ucADCCount=0; ucADCCount<6; ucADCCount++)
				{
					ucADCCount2 += (ucADCCount<<1);
					if (ulDataH>=ADCTable[ucADCCount2])
					{
						break;
					}
				}

				if (ucADCCount<6)
				{
					ucPowerPercent = ADCTable2[ucADCCount2+1];
				}
				else
				{
					ucPowerPercent = 0;
				}

				
				if(gbLoadState)
				{
					if ((enState == EN_STATE_CHARGE) ||(enState == EN_STATE_CHARGE_OK))
					{
						if (gbChargeOK)
						{
							ucPowerPercent = 5;
						}
					}					
				}			
				else
				{
					ucPowerPercent = ucPercent;
				}
					
			}
		}
		else
		{
			ucPrevDataH = ulDataH;
			ucPrevDataL	= ulDataL;
			ucpowerpercentCount = 0;
		}
	}

	FEOC = 0;
	ADM = 0x02;	//ADC input channel mode: AIN4
	FGCHS = 1;	//AIN channel enable
	FADENB = 1;
	//_DELAY(100); //User support DELAY function
	FADCIRQ = 0;
	//FADCIEN = 1;	//Interrupt enable
	ADR = 0x60;	//ADC clock: 1.000000MHZ,ADC resolution: -1
	//VREFH = 0x00;	//Internal VREFH: NULL
	FEVHENB = 1;	//Internal VREFH disable
	FADS = 1;

	gucADCSel = 1;
	return;
}
#endif
#endif
void AIN2ADCHandel(void)
{
	unsigned char ulDataH,  ulDataL;
	static unsigned char ucPrevDataH, ucPrevDataL;
	static unsigned char ucpowerpercentCount = 0;  // confirm powerpercent is ok

	ulDataH = ADB;
	ulDataL = ADR&0x0F;
	if((!gbBootingState) & (ucPrevDataH==ulDataH)&(ucPrevDataL==ulDataL))
	{
		ucpowerpercentCount++;
		if(ucpowerpercentCount == 3)
		{
			ucpowerpercentCount = 0;

			if((ulDataH==0))
			{
				if(ulDataL<=0x01)
				{
					gbDeviceInsert = FALSE;
				}
				else
				{
					gbDeviceInsert = TRUE;

					if (ulDataL<=4)
						gbOutputChargeOK = TRUE;
					else
						gbOutputChargeOK = FALSE;
				}				
			}
			else
			{
				gbDeviceInsert = TRUE;
			}
			
			//0.190V=311=0x137	0.180V=295=0x127		0.184V
			//if ((ulData>0x0127)&&(ulData<0x0137))
			if (ulDataH==0x12)
			{
				gbProtectionSleep = TRUE;//go sleep
			}
			if (ulDataH==0x13)
			{
				gbProtectionSleep = TRUE;//go sleep
			}
				
			/*
			if (ulDataH==0x12)
			{
				if((ulDataL>0x0)&&(ulDataL<0xF))
					gbProtectionSleep = TRUE;//go sleep
			}

			if (ulDataH==0x13)
			{
				if((ulDataL>0x0)&&(ulDataL<0xF))
					gbProtectionSleep = TRUE;//go sleep
			}
			*/
		}
	}
	else
	{
		ucPrevDataH = ulDataH;
		ucPrevDataL	= ulDataL;
		ucpowerpercentCount = 0;
		
	}

	FADENB = 0;
	ADM = 0x04;	//ADC input channel mode: AIN4
	FGCHS = 1;	//AIN channel enable
	ADR = 0x00;	//ADC clock: 1.000000MHZ,ADC resolution: -1
	VREFH = 0x00;	//Internal VREFH: NULL
	FEVHENB = 1;	//Internal VREFH disable
	FADENB = 1;
	FADCIRQ = 0;
	FADCIEN = 1;	//Interrupt enable
	FEOC = 0;
	//FADS = 1;					
	
	gucADCSel = 0;
	g5MsTimeoutCount = 0;
}

#endif

void ADC_Process(void)
{
	unsigned char ucMax, ucMin;
	unsigned long ucADCValSum = 0;	
	
	//Init_ADC();
	//FADS = 1;
	
	//while(!FEOC);
	
	//FADS = 0;
	ucADCValBuf[ucADCCount] = ADB;
	ucADCCount++;

	if(ucADCCount>=6)
	{
		//ucADCCount = 0;
		ucMax=0, ucMin=0xff;
		for(ucADCCount=0; ucADCCount<6; ucADCCount++)
		{
			ucADCValSum+=ucADCValBuf[ucADCCount];

			if(ucADCValBuf[ucADCCount]<ucMin)
			{
				ucMin = ucADCValBuf[ucADCCount];
			}

			if(ucADCValBuf[ucADCCount]>ucMax)
			{
				ucMax = ucADCValBuf[ucADCCount];
			}                        
		}

		ucADCValSum -= ucMax;
		ucADCValSum -= ucMin;

		ucMax = ucADCValSum>>2;	//adc val
		
		ucMin = 5;
		if (enState == EN_STATE_IDLE)
		{
			ucMin = 0;
		}
		if (enState == EN_STATE_OUTPUT)
		{
			ucMin = 10;
		}
		
		for(ucADCCount=0; ucADCCount<5; ucADCCount++)
		{
			if (ucMax>=ADCTable[ucMin+ucADCCount])
			{
				break;
			}
		}

		ucMax = 0;
		if (ucADCCount<5)
		{
			ucMax = ADCTable2[ucMin+ucADCCount];
		}

/*
		if (gbChargeOK)
		{
			ucPowerPercent = 5;
		}
		else
*/
		if (gbFristPowerOn)
		{
			ucPowerPercent = ucMax;
		}
		else
		{
			if (enState == EN_STATE_CHARGE)
			{
				if(ucMax>=ucPowerPercent)
					ucPowerPercent = ucMax;	
				//if (ucPowerPercent==10)
					//gbChargeOK = TRUE;
			}					
			if(enState == EN_STATE_OUTPUT)
			{
				if(ucMax<=ucPowerPercent)
					ucPowerPercent = ucMax;
			}

			//ucPowerPercent = ucMax;
		}

		ucADCCount = 0;
	}

	FADENB = 0;
	ADM = 0x02;	//ADC input channel mode: AIN2
	FGCHS = 1;	//AIN channel enable
	FADENB = 1;
	ADR = 0x00;	//ADC clock: 1.000000MHZ,ADC resolution: -1
	VREFH = 0x00;	//Internal VREFH: NULL
	FEVHENB = 1;	//Internal VREFH disable
	FADENB = 1;
	FADCIRQ = 0;
	FADCIEN = 1;	//Interrupt enable
	FEOC = 0;
	//FADS = 1;					
	
	gucADCSel = 1;
	g5MsTimeoutCount = 0;
}

